﻿using BBCore.Application;
using BBCore.Server.Components;
using BootstrapBlazor.Components;
using FreeSql;
using BBCore.Server.Seed;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.SignalR;
using NetCore.AutoRegisterDi;
using NLog.Web;
using System.Reflection;
using System.Text;
using BBCore.Infrastructure.Helps;
using BBCore.Server.Data;
using BBCore.Application.Admins;
using BBCore.Server.Services;
/*
 切换不同数据库时注意事项
1.FreeSql.DataType.数据库
2.是否注释UseAutoSyncStructure(true)
3.builder.Services.AddDb(Fsql);//种子数据初始化
 */

var builder = WebApplication.CreateBuilder(args);

//删除所有其他的关于日志记录的配置
builder.Logging.ClearProviders();
//注入nlog
builder.Host.UseNLog();

var MasterDB = builder.Configuration["MasterDB:ConnString"];
IFreeSql Fsql = new FreeSql.FreeSqlBuilder()
    //数据库连接
    .UseConnectionString(FreeSql.DataType.SqlServer, MasterDB)
    //自动同步实体结构到数据库，正式环境慎用,危险!正式环境慎用,危险!正式环境慎用,危险!正式环境慎用,危险!正式环境慎用,危险!正式环境慎用,危险!正式环境慎用,危险!
    .UseAutoSyncStructure(true)
    //调试sql语句输出,请务必定义成 Singleton 单例模式
    .UseMonitorCommand(cmd => System.Console.WriteLine(cmd.CommandText))
    .Build(); //be sure to define as singleton mode

Fsql.Aop.SyncStructureAfter+= (s, e) =>
{
    //迁移的 SQL 语句长啥样，你可能会好奇
    if (!string.IsNullOrEmpty(e.Sql))
    {
        NLog.LogManager.GetCurrentClassLogger().Info("耗时:" + e.ElapsedMilliseconds + "毫秒\r\n" + "审计迁移脚本执行的SQL语句:\r\n" + e.Sql + "\r\n");
    }    
};
Fsql.Aop.CommandAfter += (s, e) =>
{
    //打印SQL到日志的信息
    NLog.LogManager.GetCurrentClassLogger().Info("耗时:" + e.ElapsedMilliseconds + "毫秒\r\n" + "执行的SQL语句:\r\n" + e.Command.CommandText + "\r\n");
};
BaseEntity.Initialization(Fsql, null);//BaseEntity注入Freesql
builder.Services.AddSingleton<IFreeSql>(Fsql);
builder.Services.AddSingleton(Fsql);//注入Freesql

builder.Services.AddDb(Fsql);//种子数据初始化

// Add services to the container.处理不同编码问题
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
builder.Services.AddControllers();



builder.Services.AddServerSideBlazor().AddCircuitOptions(options => options.DetailedErrors = true);//在浏览器中显示详细的出错信息
builder.Services.AddRazorComponents().AddInteractiveServerComponents();

builder.Services.AddBootstrapBlazor();
//builder.Services.AddScoped(typeof(IDataService<>), typeof(DefaultDataService<>));
builder.Services.AddSingleton(typeof(IDataService<>), typeof(FreesqlDataService<>));
builder.Services.AddSingleton(typeof(IDataQueryService<>), typeof(DataQueryService<>));
builder.Services.AddSingleton<RecordLockService>();
//写入Cookie
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(config =>
{
    config.LoginPath = new PathString("/Login");
    config.AccessDeniedPath = new PathString("/NotAuth");//拒绝访问的路由地址
    config.LogoutPath = new PathString("/api/Account/Logout");

});
//CBAC基于声明的授权
builder.Services.AddAuthorizationBuilder()
    .AddPolicy(BBCore_Constant.policy_IsAdmin, policy => policy.RequireUserName(BBCore_Constant.adminName));

#region 批量依赖注入
var modelAssembly = Assembly.Load(ServiceAutoDI.GetAssemblyName());//可以是其他程序集
builder.Services.RegisterAssemblyPublicNonGenericClasses(modelAssembly)//将获取到的程序集信息注册到我们的依赖注入容器中
                .Where(c => c.Name.EndsWith("Service"))
                .AsPublicImplementedInterfaces(ServiceLifetime.Scoped);
#endregion
builder.Services.AddCascadingAuthenticationState();

// 增加 Table 导出服务
builder.Services.AddBootstrapBlazorTableExportService();

// 增加 Html2Pdf 服务
builder.Services.AddBootstrapBlazorHtml2PdfService();

// 增加 SignalR 服务数据传输大小限制配置
builder.Services.Configure<HubOptions>(option => option.MaximumReceiveMessageSize = null);

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
}

app.UseHttpsRedirection();

app.UseStaticFiles();
app.UseAntiforgery();

app.UseAuthentication();
app.UseAuthorization();
app.MapDefaultControllerRoute();
app.MapRazorComponents<App>().AddInteractiveServerRenderMode();

app.Run();
